using System;
using NWrapper.Cache;
using NWrapper.Config;
using NWrapper.Logging;
using NWrapper.Repositories;

namespace NWrapper
{
	/// <summary>
	/// The registry is a static singleton class that provides access to the 
	/// underlying services provided by NWrapper.
	/// </summary>
	public static class Registry
	{
		private static NWrapperSection _settings;
		private static IRepository _repository;
		private static CacheProxy _cache;
		private static LoggerProxy _logger;

		#region Constructors
		/// <summary>
		/// Initializes the registry using the settings in the application config file.
		/// Subsequent calls will re-initialize the registry.
		/// </summary>
		public static void Initialize()
		{
			Initialize(new Configuration().Settings);
		}
		/// <summary>
		/// Initializes the registry using the settings specified.
		/// Subsequent calls will re-initialize the registry.
		/// </summary>
		/// <param name="settings"></param>
		public static void Initialize(NWrapperSection settings)
		{
			if (settings == null)
				throw new ArgumentNullException("config");

			_settings = settings;

			_cache = new CacheProxy(settings.Cache);
			_logger = new LoggerProxy(settings.Logger);
			_repository = new RepositoryProxy(settings.Repositories);
		}
		#endregion

		#region Private Methods
		private static void AssertIsInitialized()
		{
			if (_settings == null || _cache == null || _logger == null || _repository == null)
				throw new NullReferenceException("Attempt to access Registry properties before the Registry has been initialized.");
		}
		#endregion

		#region Public Properties
		/// <summary>
		/// Gets the repository proxy.
		/// </summary>
		/// <remarks>
		/// If the registry has not been initialized, an exception is thrown.
		/// </remarks>
		public static IRepository Repository
		{
			get
			{
				AssertIsInitialized();
				return _repository;
			}
		}
		/// <summary>
		/// Gets the cache proxy.
		/// </summary>
		/// <remarks>
		/// If the registry has not been initialized, an exception is thrown.
		/// </remarks>
		public static ICache Cache
		{
			get
			{
				AssertIsInitialized();
				return _cache;
			}
		}
		/// <summary>
		/// Gets the logging proxy.
		/// </summary>
		/// <remarks>
		/// If the registry has not been initialized, an exception is thrown.
		/// </remarks>
		public static ILogger Logger
		{
			get
			{
				AssertIsInitialized();
				return _logger;
			}
		}
		#endregion
	}
}
